home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
admin
/
linuxcon.000
/
linuxcon
/
linuxconf-1.6
/
fstab
/
partition.c
< prev
Wrap
C/C++ Source or Header
|
1996-03-01
|
5KB
|
281 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../misc/misc.h"
#include "../netconf/netconf.h"
#include "fstab.h"
#include "fstab.m"
/*
describe one entry of the partition table
*/
PUBLIC PARTITION::PARTITION(
const char *_dev,
int _id,
long _size)
{
dev =strdup_err(_dev);
id = _id;
size = _size;
drive_letter = ' ';
}
PUBLIC PARTITION::~PARTITION()
{
free (dev);
}
/*
Set the drive letter DOS would normally associate with this
partition.
*/
PUBLIC void PARTITION::setdosdrive(char letter)
{
drive_letter = letter;
}
/*
Get the drive letter DOS would normally associate with this
partition.
*/
PUBLIC char PARTITION::getdosdrive()
{
return drive_letter;
}
/*
Return != 0 if the partition is a DOS one.
*/
PUBLIC int PARTITION::isdos()
{
return id == PARTITION_DOS_ID12
|| id == PARTITION_DOS_ID16
|| id == PARTITION_DOS_ID1632;
}
/*
Return != 0 if the partition is a OS/2 one.
*/
PUBLIC int PARTITION::isos2()
{
return id == PARTITION_OS2_HPFS;
}
/*
Return != if a partition is a swap.
*/
PUBLIC int PARTITION::isswap()
{
return id == PARTITION_LINUX_SWAP;
}
/*
Return != if a partition is a native linux one (ext2).
*/
PUBLIC int PARTITION::islinux()
{
/* #Specification: fsconf / partition / linux native
fsconf does not differentiate minix / xiafs / ext and
ext2 partition. It assumes that a "Linux native"
partition is always a ext2 one.
*/
return id == PARTITION_LINUX_NATIVE;
}
/*
Return the path of the device controlling a partition.
*/
PUBLIC const char *PARTITION::getdevice()
{
return dev;
}
/*
Return the size (in block) of the partition
*/
PUBLIC long PARTITION::getsize()
{
return size;
}
/*
Return the ID (in block) of the partition
*/
PUBLIC int PARTITION::getid()
{
return id;
}
PUBLIC void PARTITION::formatinfo(char *buf)
{
char drive[3];
drive[0] = '\0';
if (drive_letter != ' '){
sprintf (drive,"%c:",drive_letter);
}
sprintf (buf,"%7ldM %-5s(%02x) %s"
,size/1024,getos()
,id,drive);
}
/*
Return the name of the OS related to this partition if it is a
filesystem.
Return "" is unknown
*/
PUBLIC const char *PARTITION::getos()
{
char *ret = "";
if (isdos()){
ret = "Dos";
}else if (islinux()){
ret = "Linux";
}else if (isswap()){
ret = "Swap";
}else if (isos2()){
ret = "Os/2";
}
return ret;
}
PUBLIC PARTITIONS::PARTITIONS()
{
DAEMON *dae = daemon_find ("fdisk");
if (dae != NULL){
char cmd[200];
sprintf (cmd,"%s -l",dae->getpath());
FILE *fin = popen (cmd,"r");
if (fin != NULL){
char buf[300];
while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
if(buf[0] == '/'){
char t[7][30];
int nb = sscanf (buf
,"%s %s %s %s %s %s %s"
,t[0],t[1],t[2],t[3],t[4],t[5]
,t[6]);
if (nb != 7){
xconf_error (
MSG_U(E_IVLDFDISK
,"Invalid output format for fdisk\n%s")
,buf);
}else{
int offset = 4;
if(strcmp(t[1],"*")==0) offset = 5;
int id;
sscanf (t[offset+1],"%x",&id);
add (new PARTITION(t[0],id
,atoi(t[offset])));
}
}
}
}
pclose (fin);
}
setdosdrive();
}
PUBLIC PARTITION *PARTITIONS::getitem(int no) const
{
return (PARTITION*)ARRAY::getitem(no);
}
/*
Locate one partition in the table using its device path as key.
Return NULL if not found.
*/
PUBLIC PARTITION *PARTITIONS::getitem(const char *device) const
{
PARTITION *ret = NULL;
for (int i=0; i<getnb(); i++){
PARTITION *p = getitem(i);
if (strcmp(p->getdevice(),device)==0){
ret = p;
break;
}
}
return ret;
}
/*
Assign DOS drive letter to DOS partition
*/
PROTECTED void PARTITIONS::setdosdrive()
{
/* #Specification: partitions / dos drive / how it works
All this is very complicate.
DOS allocate C on the first non extended DOS partition
of the first drive.
It then allocate D if possible on the first non extended
DOS partition of the second drive.
From there is get back to the first drive and allocate
a letter to all DOS extended partition. After that
it goes and finished the second hard drive.
I have no idea what happen when you get more than
four drives. DOS does not support it if I am right.
Some info is needed here.
*/
char drive = 'C';
char minpart = '1';
char maxpart = '4';
for (int pass=0; pass<2; pass++){
for (int d='a'; d<='b'; d++){
for (int i=minpart; i<=maxpart; i++){
char buf[10];
sprintf (buf,"/dev/hd%c%c",d,i);
PARTITION *p = getitem (buf);
if (p != NULL
&& p->isdos()){
p->setdosdrive(drive);
drive++;
if (pass == 0) break;
}
}
}
minpart = '5';
maxpart = '8';
}
}
/*
Probe the partition table of all devices.
This take some time since fdisk is spawned to get it. So the
result is kept from call to call.
The returned object should not be deleted.
*/
PARTITIONS *partition_load()
{
static PARTITIONS *parts = NULL;
if (parts == NULL){
parts = new PARTITIONS;
}
return parts;
}
#ifdef TEST
int main (int , char *[])
{
PARTITIONS parts;
for (int i=0; i<parts.getnb(); i++){
PARTITION *p = parts.getitem(i);
char *type = "???";
if (p->isswap()){
type = "Swap";
}else if (p->isdos()){
type = "Dos";
}else if (p->islinux()){
type = "Linux";
}
printf ("%s %ld %s\n",p->getdevice(),p->getsize()
,type);
}
return 0;
}
#endif